package cn.zxf.note.note.note;

import cn.zxf.note.common.jpa.AbstractDao;
import cn.zxf.note.note.note.dto.NoteSingleLineDto;
import com.github.zengxf.common.domain.Page;
import com.github.zengxf.common.domain.Pair;
import com.github.zengxf.common.utils.DateUtils;
import com.github.zengxf.common.utils.ListUtils;
import com.github.zengxf.sqlbuilder.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * Created by zengxf on 2019/7/24.
 */
@Component
public class NoteDao extends AbstractDao {

    public Note findByDayAndTitle(Integer userId, LocalDate date, String title) {
        Pair<LocalDateTime> dates = DateUtils.toTimes(date);
        DbCriteriaGroup where = DbCriteriaGroup.ofAnd()
                .addItem(DbCriteria.of("user_id", DbCriteriaType.EQ, userId))
                .addItem(DbCriteria.of("status", DbCriteriaType.EQ, NoteStatusEnum.NORMAL.code))
                .addItem(DbCriteria.of("title", DbCriteriaType.EQ, title))
                .addItem(DbCriteria.of("create_date", DbCriteriaType.BETWEEN, dates.v1, dates.v2));
        SqlResult listSql = SelectBuilder.of()
                .table("note")
                .where(where)
                .build();
        RowMapper<Note> rm = BeanPropertyRowMapper.newInstance(Note.class);
        List<Note> list = super.namedJdbc.query(listSql.getSql(), listSql.getParam(), rm);
        return ListUtils.one(list);
    }

    public Page<NoteSingleLineDto> pageByType(Integer userId, Integer typeId, Integer pageIndex, Integer pageSize) {
        DbCriteriaGroup where = DbCriteriaGroup.ofAnd()
                .addItem(DbCriteria.of("user_id", DbCriteriaType.EQ, userId))
                .addItem(DbCriteria.of("status", DbCriteriaType.EQ, NoteStatusEnum.NORMAL.code))
                .addItem(DbCriteria.of("type_id", DbCriteriaType.EQ, typeId));

        SelectBuilder builder = SelectBuilder.of()
                .table("note")
                .addField("id")
                .addField("title")
                .addField("LEFT(content, 20)", "contentSingleLine")
                .addField("create_date")
                .where(where)
                .setSort(DbSort.of().desc("create_date"))
                .page(pageIndex, pageSize);
        SqlResult listSql = builder.build();
        RowMapper<NoteSingleLineDto> rm = BeanPropertyRowMapper.newInstance(NoteSingleLineDto.class);
        List<NoteSingleLineDto> list = super.namedJdbc.query(listSql.getSql(), listSql.getParam(), rm);

        SqlResult countSql = builder.copyForCount().build();
        Integer total = super.namedJdbc.queryForObject(countSql.getSql(), countSql.getParam(), Integer.class);
        return Page.of(total, list);
    }

    public Page<NoteSingleLineDto> pageSearch(
            Integer userId, Integer type, String keyword, Integer pageIndex, Integer pageSize
    ) {
        DbCriteriaGroup where = DbCriteriaGroup.ofAnd()
                .addItem(DbCriteria.of("n.user_id", DbCriteriaType.EQ, userId))
                .addItem(DbCriteria.of("n.status", DbCriteriaType.EQ, NoteStatusEnum.NORMAL.code));
        if (StringUtils.isNotEmpty(keyword)) {
            where.addGroup(DbCriteriaGroup.ofOr()
                    .addItem(DbCriteria.of("n.title", DbCriteriaType.LIKE, keyword))
                    .addItem(DbCriteria.of("n.content", DbCriteriaType.LIKE, keyword))
            );
        }
        if (!Objects.equals(-1, type))
            where.addItem(DbCriteria.eq("type_id", type));

        SelectBuilder builder = SelectBuilder.of()
                .table("note AS n")
                .addJoin(DbJoin.left(
                        "note_type AS nt",
                        DbCriteria.ofLiteral("n.type_id", DbCriteriaType.EQ, "nt.id"))
                )
                .addField("n.id", "id")
                .addField("nt.name", "typeName")
                .addField("n.title", "title")
                .addField("LEFT(n.content, 20)", "contentSingleLine")
                .addField("n.create_date", "create_date")
                .where(where)
                .setSort(DbSort.of().desc("create_date"))
                .page(pageIndex, pageSize);
        SqlResult listSql = builder.build();
        RowMapper<NoteSingleLineDto> rm = BeanPropertyRowMapper.newInstance(NoteSingleLineDto.class);
        List<NoteSingleLineDto> list = super.namedJdbc.query(listSql.getSql(), listSql.getParam(), rm);

        SqlResult countSql = builder.copyForCount().build();
        Integer total = super.namedJdbc.queryForObject(countSql.getSql(), countSql.getParam(), Integer.class);
        return Page.of(total, list);
    }

    public void transfer(Integer userId, Integer fromTypeId, Integer toTypeId) {
        SqlResult res = UpdateBuilder.of()
                .table("note")
                .addSet(DbSet.of("type_id", toTypeId))
                .where(DbCriteriaGroup.ofAnd(
                        DbCriteria.eq("user_id", userId),
                        DbCriteria.eq("type_id", fromTypeId)
                ))
                .build();
        super.namedJdbc.update(res.sql, res.param);
    }

}
